<template>
  <div class="min-h-screen bg-gray-50 py-8">
    <div class="max-w-4xl mx-auto px-4">
      <h1 class="text-3xl font-bold text-gray-900 mb-8 text-center">日志分析器</h1>
      
      <!-- 文件上传区域 -->
      <div class="bg-white rounded-lg shadow-md p-6 mb-8">
        <h2 class="text-xl font-semibold mb-4">上传日志压缩包</h2>
        <div class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center">
          <input
            ref="fileInput"
            type="file"
            accept=".zip,.rar,.7z,.tar,.gz"
            @change="handleFileSelect"
            class="hidden"
          />
          <div v-if="!selectedFile" @click="fileInput?.click()" class="cursor-pointer">
            <svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none" viewBox="0 0 48 48">
              <path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
            </svg>
            <p class="mt-2 text-sm text-gray-600">点击选择压缩包文件</p>
            <p class="text-xs text-gray-500">支持 ZIP, RAR, 7Z, TAR, GZ 格式</p>
          </div>
          <div v-else class="space-y-4">
            <div class="flex items-center justify-center space-x-2">
              <svg class="h-8 w-8 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"></path>
              </svg>
              <span class="text-sm font-medium text-gray-900">{{ selectedFile.name }}</span>
            </div>
            <div class="flex space-x-4 justify-center">
              <button
                @click="uploadFile"
                :disabled="uploading"
                class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 disabled:opacity-50"
              >
                {{ uploading ? '上传中...' : '上传文件' }}
              </button>
              <button
                @click="clearFile"
                class="bg-gray-600 text-white px-4 py-2 rounded-md hover:bg-gray-700"
              >
                重新选择
              </button>
            </div>
          </div>
        </div>
      </div>

      <!-- 搜索区域 -->
      <div class="bg-white rounded-lg shadow-md p-6 mb-8">
        <h2 class="text-xl font-semibold mb-4">搜索日志</h2>
        <div class="flex space-x-4 mb-4">
          <input
            v-model="searchQuery"
            type="text"
            placeholder="输入搜索关键词..."
            class="flex-1 border border-gray-300 rounded-md px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
            @keyup.enter="searchLogs"
          />
          <button
            @click="searchLogs"
            :disabled="!searchQuery.trim() || searching"
            class="bg-green-600 text-white px-6 py-2 rounded-md hover:bg-green-700 disabled:opacity-50"
          >
            {{ searching ? '搜索中...' : '搜索' }}
          </button>
        </div>
        <div class="flex items-center space-x-4 text-sm text-gray-600">
          <label class="flex items-center">
            <input v-model="caseSensitive" type="checkbox" class="mr-2" />
            区分大小写
          </label>
          <label class="flex items-center">
            <input v-model="useRegex" type="checkbox" class="mr-2" />
            正则表达式
          </label>
        </div>
      </div>

      <!-- 搜索结果 -->
      <div v-if="searchResults.length > 0" class="bg-white rounded-lg shadow-md p-6">
        <h2 class="text-xl font-semibold mb-4">
          搜索结果 ({{ searchResults.length }} 条匹配)
        </h2>
        <div class="space-y-4 max-h-96 overflow-y-auto">
          <div
            v-for="(result, index) in searchResults"
            :key="index"
            class="border-l-4 border-blue-500 pl-4 py-2 bg-gray-50 rounded-r-md"
          >
            <div class="text-sm text-gray-600 mb-1">
              <span class="font-medium">{{ result.filename }}</span>
              <span class="mx-2">第{{ result.lineNumber }}行</span>
            </div>
            <div class="font-mono text-sm bg-white p-2 rounded border" v-html="highlightMatch(result.line)"></div>
          </div>
        </div>
      </div>

      <!-- 状态消息 -->
      <div v-if="message" class="mt-4 p-4 rounded-md" :class="messageClass">
        {{ message }}
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
interface SearchResult {
  filename: string;
  lineNumber: number;
  line: string;
}

interface UploadResponse {
  message: string;
  filesProcessed: number;
}

interface SearchResponse {
  results: SearchResult[];
}

const selectedFile = ref<File | null>(null);
const uploading = ref(false);
const searchQuery = ref('');
const searching = ref(false);
const searchResults = ref<SearchResult[]>([]);
const caseSensitive = ref(false);
const useRegex = ref(false);
const message = ref('');
const messageType = ref<'success' | 'error' | 'info'>('info');
const fileInput = ref<HTMLInputElement>();

const messageClass = computed(() => {
  switch (messageType.value) {
    case 'success':
      return 'bg-green-100 border border-green-400 text-green-700';
    case 'error':
      return 'bg-red-100 border border-red-400 text-red-700';
    default:
      return 'bg-blue-100 border border-blue-400 text-blue-700';
  }
});

function handleFileSelect(event: Event) {
  const file = (event.target as HTMLInputElement).files?.[0];
  if (file) {
    selectedFile.value = file;
  }
}

function clearFile() {
  selectedFile.value = null;
  if (fileInput.value) {
    fileInput.value.value = '';
  }
}

async function uploadFile() {
  if (!selectedFile.value) return;

  uploading.value = true;
  message.value = '';

  try {
    const formData = new FormData();
    formData.append('file', selectedFile.value);

    const response = await $fetch<UploadResponse>('/api/upload', {
      method: 'POST',
      body: formData
    });

    messageType.value = 'success';
    message.value = response.message || '压缩包上传并解析成功！';
  } catch (error: any) {
    messageType.value = 'error';
    message.value = error.data?.message || '上传失败，请重试';
  } finally {
    uploading.value = false;
  }
}

async function searchLogs() {
  if (!searchQuery.value.trim()) return;

  searching.value = true;
  message.value = '';
  searchResults.value = [];

  try {
    const response = await $fetch<SearchResponse>('/api/search', {
      method: 'POST',
      body: {
        query: searchQuery.value,
        caseSensitive: caseSensitive.value,
        useRegex: useRegex.value
      }
    });

    searchResults.value = response.results || [];
    
    if (searchResults.value.length === 0) {
      messageType.value = 'info';
      message.value = '没有找到匹配的结果';
    } else {
      message.value = '';
    }
  } catch (error: any) {
    messageType.value = 'error';
    message.value = error.data?.message || '搜索失败，请重试';
  } finally {
    searching.value = false;
  }
}

function highlightMatch(line: string): string {
  if (!searchQuery.value.trim()) return escapeHtml(line);

  let query = searchQuery.value;
  let flags = caseSensitive.value ? 'g' : 'gi';
  
  try {
    let regex;
    if (useRegex.value) {
      regex = new RegExp(query, flags);
    } else {
      regex = new RegExp(escapeRegExp(query), flags);
    }
    
    return escapeHtml(line).replace(regex, '<mark class="bg-yellow-200">$&</mark>');
  } catch (e) {
    return escapeHtml(line);
  }
}

function escapeHtml(text: string): string {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
}

function escapeRegExp(string: string): string {
  return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
</script>

<style>
/* 全局样式已通过Tailwind CSS类处理 */
</style>
